﻿using KPIS.GERP.Models;
using KPIS.GERP.Models.Class;
using KPIS.GERP.Models.ICM;
using KPIS.GERP.Models.SYS;
using System;
using System.Data;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.ServiceModel;
using System.Web.Mvc;

namespace KPIS.GERP.WCF.GIMS
{
    [ServiceContract]
    public interface IRepairService
    {
        [OperationContract]
        List<SelectListItem> SelectListAsset();

        [OperationContract]
        List<SelectListItem> SelectListJobsite();

        [OperationContract]
        List<SelectListItem> SelectListDealer();

        [OperationContract]
        List<SelectListItem> SelectListWarehouse();

        [OperationContract]
        List<SelectListItem> SelectListRepairStatus(IcmMasLookUpType.LookUpType lookUpType);

        [OperationContract]
        IEnumerable<Asset> SelectAsset(Asset criteriaModel = null, List<string> includeSubObjectString = null);

        [OperationContract]
        IEnumerable<InventoryRepair> SelectRepair(InventoryRepair criteriaModel = null, List<string> includeSubObjectString = null);

        [OperationContract]
        int Insert(InventoryRepair model, int intCreateByUserId);

        [OperationContract]
        void Update(InventoryRepair model, int updateByUserId);
        
        [OperationContract]
        void Delete(int id, int deleteByUserId);

        [OperationContract]
        void UpdateAssetStatus(int RepairStatusId, string AssetCode, int updateByUserId);

        [OperationContract]
        string GetWarrantyTime(int AssetId);

        [OperationContract]
        string[] RepairName(int RepairId);

        [OperationContract]
        string[] AssetName(int RepairId);

    }
    
    public class RepairService : IRepairService
    {
        public List<SelectListItem> SelectListAsset()
        {
            var data = new List<SelectListItem>();
            var context = new GERPContext(false);
            try
            {
                // เลือกครุภัณฑ์ทั้งหมด
                var query1 = (from a in context.Assets
                              where a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                              select a).ToList();

                // เลือกครุภัณฑ์ที่มีสถานะ "กำลังซ่อมแซม" เท่านั้น
                var query2 = (from m in context.Assets
                              join n in context.InventoryRepairs on m.AssetCode equals n.AssetCode
                              where m.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                              && n.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                              && n.RepairStatus == 70
                              select m).ToList();

                // Listของรายการครุภัณฑ์ โดยที่ตัดครุภัณฑ์ที่มีสถานะ "กำลังซ่อมแซม" ออก
                var listAsset = query1.Except(query2).ToList();

                if (listAsset.Count > 0)
                {
                    foreach (var Asset in listAsset)
                    {
                        var item = new SelectListItem { Text = Asset.AssetName+" : "+Asset.SerialNumber, Value = Asset.AssetId.ToString() };
                        data.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return data;
        }

        public List<SelectListItem> SelectListJobsite()
        {
            var data = new List<SelectListItem>();
            data.Add(new SelectListItem { Selected = true, Text = "ไม่ระบุ", Value = "" });

            var context = new GERPContext(false);
            try
            {
                List<Models.HRM.JobSite> listJobsite = (from a in context.JobSites
                                                    where a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                                    select a).ToList();

                if (listJobsite.Count > 0)
                {
                    foreach (var Jobsite in listJobsite)
                    {
                        var item = new SelectListItem { Text = Jobsite.Name, Value = Jobsite.JobSiteId.ToString() };
                        data.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return data;
        }

        public List<SelectListItem> SelectListDealer()
        {
            var data = new List<SelectListItem>();
            data.Add(new SelectListItem { Selected = true, Text = "ไม่ระบุ", Value = "" });

            var context = new GERPContext(false);
            try
            {
                List<Models.ICM.MasContact> listDealer = (from a in context.MasContacts
                                                        where a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                                        select a).ToList();

                if (listDealer.Count > 0)
                {
                    foreach (var Dealer in listDealer)
                    {
                        var item = new SelectListItem { Text = Dealer.NameTh, Value = Dealer.ConId.ToString() };
                        data.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return data;
        }

        public List<SelectListItem> SelectListWarehouse()
        {
            var data = new List<SelectListItem>();
            data.Add(new SelectListItem { Selected = true, Text = "ไม่ระบุ", Value = "" });

            var context = new GERPContext(false);
            try
            {
                List<Models.ICM.Warehouse> listWarehouse = (from a in context.Warehouses
                                                               where a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                                               select a).ToList();

                if (listWarehouse.Count > 0)
                {
                    foreach (var Warehouse in listWarehouse)
                    {
                        var item = new SelectListItem { Text = Warehouse.Name, Value = Warehouse.WhId.ToString() };
                        data.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return data;
        }

        public List<SelectListItem> SelectListRepairStatus(IcmMasLookUpType.LookUpType lookUpType)
        {
            var data = new List<SelectListItem>();

            var context = new GERPContext(false);
            try
            {
                List<Models.ICM.IcmMasLookUp> listRepairStatus = (from a in context.IcmMasLookUps
                                                            where a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                                            && a.LookUpTypeId == (int)lookUpType
                                                            select a).ToList();

                if (listRepairStatus.Count > 0)
                {
                    foreach (var RepairStatus in listRepairStatus)
                    {
                        var item = new SelectListItem { Text = RepairStatus.LookUpName, Value = RepairStatus.LookUpId.ToString() };
                        data.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return data;
        }

        public IEnumerable<Asset> SelectAsset(Asset criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<Asset> query = context.Assets;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    return query.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IEnumerable<InventoryRepair> SelectRepair(InventoryRepair criteriaModel = null, List<string> includeSubObjectString = null)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    IQueryable<InventoryRepair> query = context.InventoryRepairs;

                    if (includeSubObjectString != null)
                    {
                        query = includeSubObjectString.Aggregate(query, (current, includePath) => current.Include(includePath));
                    }

                    if (criteriaModel != null)
                    {
                        object[] param;
                        query = query.Where(KPIS.GERP.Models.Class.Utility.GenerateWhereString(criteriaModel, out param), param);
                    }

                    return query.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int Insert(InventoryRepair model, int intCreateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    model.CreatedBy = intCreateByUserId;
                    model.RecordStatus = RecordStatus.UsedStatus;
                    model.CreatedWhen = DateTime.Now;
                    context.InventoryRepairs.Add(model);
                    context.SaveChanges();

                    return model.RepairId;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        public void Update(InventoryRepair model, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    model.UpdatedBy = updateByUserId;
                    model.UpdatedWhen = DateTime.Now;
                    context.Entry(model).State = EntityState.Modified;

                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        public void Delete(int id, int deleteByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    var modelToDelete = context.InventoryRepairs.Find(id);
                    if (modelToDelete == null) return;

                    context.Entry(modelToDelete).State = EntityState.Modified;
                    modelToDelete.UpdatedBy = deleteByUserId;
                    modelToDelete.UpdatedWhen = DateTime.Now;
                    modelToDelete.RecordStatus = Models.SYS.RecordStatus.DeletedStatus;
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        // Method อัพเดทสถานะครุภัณฑ์ว่า "ใช้งานได้" หรือ "ส่งซ่อม"
        public void UpdateAssetStatus(int RepairStatusId, string AssetCode, int updateByUserId)
        {
            try
            {
                using (var context = new GERPContext())
                {
                    // เช็คสถานะการซ่อมว่าเป็นสถานะ "กำลังซ่อมแซม" ?
                    if (RepairStatusId == 70)   // 70 คือ PK ของตาราง IcmMasLookUp โดยมี LookUpTypeId = 21(คือ RepairStatus)
                    {
                        var model = (from a in context.Assets
                                     where a.AssetCode == AssetCode
                                     && a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                     select a).FirstOrDefault();
                        model.AssetStatusId = 59;   // อัพเดทสถานะของครุภัณฑ์ให้เป็นสถานะ "ส่งซ่อม" ,     59 คือ PK ของตาราง IcmMasLookUp โดยมี LookUpTypeId = 18(คือ AssetStatus) 
                        model.UpdatedBy = updateByUserId;
                        model.UpdatedWhen = DateTime.Now;
                        context.Entry(model).State = EntityState.Modified;

                        context.SaveChanges();
                    }
                    // ซ่อมแซมเรียบร้อยแล้ว
                    else {
                        var model = (from a in context.Assets
                                     where a.AssetCode == AssetCode
                                     && a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                     select a).FirstOrDefault();
                        model.AssetStatusId = 57;   // อัพเดทสถานะของครุภัณฑ์ให้เป็นสถานะ "ใช้งานได้" ,     57 คือ PK ของตาราง IcmMasLookUp โดยมี LookUpTypeId = 18(คือ AssetStatus) 
                        model.UpdatedBy = updateByUserId;
                        model.UpdatedWhen = DateTime.Now;
                        context.Entry(model).State = EntityState.Modified;

                        context.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        // Method Getระยะเวลารับประกัน
        public string GetWarrantyTime(int AssetId)
        {
            try
            {
                using (var context = new GERPContext(false))
                {
                    var query = (from a in context.AssetWarrantys
                                 where a.AssetId == AssetId
                                 && a.RecordStatus != Models.SYS.RecordStatus.DeletedStatus
                                 select a.WarrantyTime).ToList();

                    if (query != null)
                    {
                        foreach (var result in query)
                        {
                            string Time = result.ToString();
                            return Time;
                        }
                    }

                    return null;
                    
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string[] RepairName(int RepairId)
        {
            using (var context = new GERPContext(false))
            {
                string Name = "";

                var x = (from a in context.InventoryRepairs
                         join b in context.Employees on a.CreatedBy equals b.EmpId
                         select new { FullName = (b.FirstName+ "  " + b.LastName) }).FirstOrDefault();

                if (x != null)
                {
                    Name = x.FullName;
                }

                return new string[] { Name };
            }
        }

        public string[] AssetName(int RepairId)
        {
            using (var context = new GERPContext(false))
            {
                string Name = "";

                var x = (from a in context.InventoryRepairs
                         join b in context.Assets on a.AssetCode equals b.AssetCode
                         select new { b.AssetName }).FirstOrDefault();

                if (x != null)
                {
                    Name = x.AssetName;
                }

                return new string[] { Name };
            }
        }
        
    }
}
